home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- ** $Id: qt/qmag.cpp 3.0.3 edited Oct 12 12:18 $
- **
- ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
- **
- ** This file is part of an example program for Qt. This example
- ** program may be used, distributed and modified without limitation.
- **
- *****************************************************************************/
-
- #include <qcombobox.h>
- #include <qpushbutton.h>
- #include <qpixmap.h>
- #include <qimage.h>
- #include <qlabel.h>
- #include <qfiledialog.h>
- #include <qregexp.h>
-
- #include <qapplication.h>
- #include <qpainter.h>
- #include <qwmatrix.h>
-
-
- class MagWidget : public QWidget
- {
- Q_OBJECT
- public:
- MagWidget( QWidget *parent=0, const char *name=0 );
-
- public slots:
- void setZoom( int );
- void setRefresh( int );
- void save();
- void multiSave();
-
- protected:
- void paintEvent( QPaintEvent * );
- void mousePressEvent( QMouseEvent * );
- void mouseReleaseEvent( QMouseEvent * );
- void mouseMoveEvent( QMouseEvent * );
- void focusOutEvent( QFocusEvent * );
- void timerEvent( QTimerEvent * );
- void resizeEvent( QResizeEvent * );
-
- private:
- void grabAround(QPoint pos);
- void grab();
-
- QComboBox *zoom;
- QComboBox *refresh;
- QPushButton *saveButton;
- QPushButton *multiSaveButton;
- QPushButton *quitButton;
- QPixmap pm; // pixmap, magnified
- QPixmap p; // pixmap
- QImage image; // image of pixmap (for RGB)
- QLabel *rgb;
- int yoffset; // pixels in addition to the actual picture
- int z; // magnification factor
- int r; // autorefresh rate (index into refreshrates)
- bool grabbing; // TRUE if qmag is currently grabbing
- int grabx, graby;
- QString multifn; // filename for multisave
- };
-
-
- #ifdef COMPLEX_GUI
- static const char *zoomfactors[] = {
- "100%", "200%", "300%", "400%", "500%",
- "600%", "700%", "800%", "1600%", 0 };
-
- static const char *refreshrates[] = {
- "No autorefresh", "50 per second", "4 per second", "3 per second", "2 per second",
- "Every second", "Every two seconds", "Every three seconds",
- "Every five seconds", "Every ten seconds", 0 };
- #endif
-
- static const int timer[] = {
- 0, 20, 250, 333, 500, 1000, 2000, 3000, 5000, 10000 };
-
-
- MagWidget::MagWidget( QWidget *parent, const char *name )
- : QWidget( parent, name)
- {
- z = 1; // default zoom (100%)
- r = 0; // default refresh (none)
-
- #ifdef COMPLEX_GUI
- int w=0, x=0, n;
-
- zoom = new QComboBox( FALSE, this );
- Q_CHECK_PTR(zoom);
- zoom->insertStrList( zoomfactors, 9 );
- connect( zoom, SIGNAL(activated(int)), SLOT(setZoom(int)) );
-
- refresh = new QComboBox( FALSE, this );
- Q_CHECK_PTR(refresh);
- refresh->insertStrList( refreshrates, 9 );
- connect( refresh, SIGNAL(activated(int)), SLOT(setRefresh(int)) );
-
- for( n=0; n<9; n++) {
- int w2 = zoom->fontMetrics().width( zoomfactors[n] );
- w = QMAX(w2, w);
- }
- zoom->setGeometry( 2, 2, w+30, 20 );
-
- x = w+34;
- w = 0;
- for( n=0; n<9; n++) {
- int w2 = refresh->fontMetrics().width( refreshrates[n] );
- w = QMAX(w2, w);
- }
- refresh->setGeometry( x, 2, w+30, 20 );
-
- saveButton = new QPushButton( this );
- Q_CHECK_PTR(saveButton);
- connect( saveButton, SIGNAL(clicked()), this, SLOT(save()) );
- saveButton->setText( "Save" );
- saveButton->setGeometry( x+w+30+2, 2,
- 10+saveButton->fontMetrics().width("Save"), 20 );
-
- multiSaveButton = new QPushButton( this );
- multiSaveButton->setToggleButton(TRUE);
- Q_CHECK_PTR(multiSaveButton);
- connect( multiSaveButton, SIGNAL(clicked()), this, SLOT(multiSave()) );
- multiSaveButton->setText( "MultiSave" );
- multiSaveButton->setGeometry( saveButton->geometry().right() + 2, 2,
- 10+multiSaveButton->fontMetrics().width("MultiSave"), 20 );
-
- quitButton = new QPushButton( this );
- Q_CHECK_PTR(quitButton);
- connect( quitButton, SIGNAL(clicked()), qApp, SLOT(quit()) );
- quitButton->setText( "Quit" );
- quitButton->setGeometry( multiSaveButton->geometry().right() + 2, 2,
- 10+quitButton->fontMetrics().width("Quit"), 20 );
- #else
- zoom = 0;
- multiSaveButton = 0;
- #endif
-
- setRefresh(1);
- setZoom(5);
-
- rgb = new QLabel( this );
- Q_CHECK_PTR( rgb );
- rgb->setText( "" );
- rgb->setAlignment( AlignVCenter );
- rgb->resize( width(), rgb->fontMetrics().height() + 4 );
-
- #ifdef COMPLEX_GUI
- yoffset = zoom->height() // top buttons
- + 4 // space around top buttons
- + rgb->height(); // color-value text height
- setMinimumSize( quitButton->pos().x(), yoffset+20 );
- resize( quitButton->geometry().topRight().x() + 2, yoffset+60 );
- #else
- yoffset = 0;
- resize(350,350);
- #endif
-
- grabx = graby = -1;
- grabbing = FALSE;
-
- setMouseTracking( TRUE ); // and do let me know what pixel I'm at, eh?
-
- grabAround( QPoint(grabx=qApp->desktop()->width()/2, graby=qApp->desktop()->height()/2) );
- }
-
-
- void MagWidget::setZoom( int index )
- {
- if (index == 8)
- z = 16;
- else
- z = index+1;
- grab();
- }
-
-
- void MagWidget::setRefresh( int index )
- {
- r = index;
- killTimers();
- if (index && !grabbing)
- startTimer( timer[r] );
- }
-
-
- void MagWidget::save()
- {
- if ( !p.isNull() ) {
- killTimers();
- QString fn = QFileDialog::getSaveFileName();
- if ( !fn.isEmpty() )
- p.save( fn, "BMP" );
- if ( r )
- startTimer( timer[r] );
- }
- }
-
- void MagWidget::multiSave()
- {
- if ( !p.isNull() ) {
- multifn = ""; // stops saving
- multifn = QFileDialog::getSaveFileName();
- if ( multifn.isEmpty() )
- multiSaveButton->setOn(FALSE);
- if ( !r )
- p.save( multifn, "BMP" );
- } else {
- multiSaveButton->setOn(FALSE);
- }
- }
-
-
- void MagWidget::grab()
- {
- if ( !isVisible() )
- return; // don't eat resources when iconified
-
- if ( grabx < 0 || graby < 0 )
- return; // don't grab until the user has said to
-
- int x,y, w,h;
-
- w = (width()+z-1)/z;
- h = (height()+z-1-yoffset)/z;
- if ( w<1 || h<1 )
- return; // don't ask too much from the window system :)
-
- x = grabx-w/2; // find a suitable position to grab from
- y = graby-h/2;
- if ( x + w > QApplication::desktop()->width() )
- x = QApplication::desktop()->width()-w;
- else if ( x < 0 )
- x = 0;
- if ( y + h > QApplication::desktop()->height() )
- y = QApplication::desktop()->height()-h;
- else if ( y < 0 )
- y = 0;
-
- p = QPixmap::grabWindow( QApplication::desktop()->winId(), x, y, w, h );
- image = p.convertToImage();
- QWMatrix m; // after getting it, scale it
- m.scale( (double)z, (double)z );
- pm = p.xForm( m );
-
- if ( !multiSaveButton || !multiSaveButton->isOn() )
- repaint( FALSE ); // and finally repaint, flicker-free
- }
-
-
- void MagWidget::paintEvent( QPaintEvent * )
- {
- if ( !pm.isNull() ) {
- QPainter paint( this );
- paint.drawPixmap( 0, zoom ? zoom->height()+4 : 0, pm,
- 0,0, width(), height()-yoffset );
- }
- }
-
-
- void MagWidget::mousePressEvent( QMouseEvent *e )
- {
- if ( !grabbing ) { // prepare to grab...
- grabbing = TRUE;
- killTimers();
- grabMouse( crossCursor );
- grabx = -1;
- graby = -1;
- } else { // REALLY prepare to grab
- grabx = mapToGlobal(e->pos()).x();
- graby = mapToGlobal(e->pos()).y();
- }
- }
-
-
-
- void MagWidget::mouseReleaseEvent( QMouseEvent * e )
- {
- if ( grabbing && grabx >= 0 && graby >= 0 ) {
- grabbing = FALSE;
- grabAround(e->pos());
- releaseMouse();
- }
- }
-
- void MagWidget::grabAround(QPoint pos)
- {
- int rx, ry;
- rx = mapToGlobal(pos).x();
- ry = mapToGlobal(pos).y();
- int w = QABS(rx-grabx);
- int h = QABS(ry-graby);
- if ( w > 10 && h > 10 ) {
- int pz;
- pz = 1;
- while ( w*pz*h*pz < width()*(height()-yoffset) &&
- w*pz < QApplication::desktop()->width() &&
- h*pz < QApplication::desktop()->height() )
- pz++;
- if ( (w*pz*h*pz - width()*(height()-yoffset)) >
- (width()*(height()-yoffset) - w*(pz-1)*h*(pz-1)) )
- pz--;
- if ( pz < 1 )
- pz = 1;
- if ( pz > 8 )
- pz = 8;
- if ( zoom )
- zoom->setCurrentItem( pz-1 );
-
- z = pz;
- grabx = QMIN(rx, grabx) + w/2;
- graby = QMIN(ry, graby) + h/2;
- resize( w*z, h*z+yoffset );
- }
- grab();
- if ( r )
- startTimer( timer[r] );
- }
-
-
- void MagWidget::mouseMoveEvent( QMouseEvent *e )
- {
- if ( grabbing || pm.isNull() ||
- e->pos().y() > height() - (zoom ? zoom->fontMetrics().height() - 4 : 0) ||
- e->pos().y() < (zoom ? zoom->height()+4 : 4) ) {
- rgb->setText( "" );
- } else {
- int x,y;
- x = e->pos().x() / z;
- y = (e->pos().y() - ( zoom ? zoom->height() : 0 ) - 4) / z;
- QString pixelinfo;
- if ( image.valid(x,y) )
- {
- QRgb px = image.pixel(x,y);
- pixelinfo.sprintf(" %3d,%3d,%3d #%02x%02x%02x",
- qRed(px), qGreen(px), qBlue(px),
- qRed(px), qGreen(px), qBlue(px));
- }
- QString label;
- label.sprintf( "x=%d, y=%d %s",
- x+grabx, y+graby, (const char*)pixelinfo );
- rgb->setText( label );
- }
- }
-
-
- void MagWidget::focusOutEvent( QFocusEvent * )
- {
- rgb->setText( "" );
- }
-
-
- void MagWidget::timerEvent( QTimerEvent * )
- {
- grab();
- /*
- if ( multiSaveButton->isOn() && !multifn.isEmpty() ) {
- QRegExp num("[0-9][0-9]*");
- int start;
- int len;
- if ((start=num.match(multifn,0,&len))>=0)
- multifn.replace(num,
- QString().setNum(multifn.mid(start,len).toInt()+1)
- );
- p.save( multifn, "BMP" );
- }
- */
- }
-
-
- void MagWidget::resizeEvent( QResizeEvent * )
- {
- rgb->setGeometry( 0, height() - rgb->height(), width(), rgb->height() );
- grab();
- }
-
-
- #include "qmag.moc"
-
-
- int main( int argc, char **argv )
- {
- QApplication a( argc, argv );
- MagWidget m;
- a.setMainWidget( &m );
- m.show();
- return a.exec();
- }
-